<?php
declare (strict_types = 1);

namespace app\common\command;

use think\console\Command;
use think\console\Input;
use think\console\input\Argument;
use think\console\input\Option;
use think\console\Output;
use Swoole\Coroutine;
class Chat extends Command
{
    private $port=0;
    private $timerId=0;
    protected function configure()
    {
        // 指令配置
        $this->setName('Chat')
            ->addArgument('status', Argument::OPTIONAL, "start")
            ->setDescription('the Chat command');
 
    }

    protected function execute(Input $input, Output $output)
    {
        $this->port=8501;
        $status=$input->getArgument('status');
        if(!empty($status)&&$status=='start'){
            file_put_contents("websocket.log",'start service'.PHP_EOL,FILE_APPEND);
            $this->startService();
        }
        if(!empty($status)&&$status=='stop'){
            file_put_contents("websocket.log",'stop service'.PHP_EOL,FILE_APPEND);
            // 停止服务
            $this->stopService();
        }
        if(!empty($status)&&$status=='show'){
            file_put_contents("websocket.log",'show port'.PHP_EOL,FILE_APPEND);
            $output->writeln(json_encode(shell_exec("netstat -ntulp|grep ". $this->port)));
        }
    }
    //停止服务
    public function stopService(){
        $managerPid=cache('master_pid');
        $masterPid=cache('manager_pid');
        if(!empty($managerPid)&&!empty($masterPid)){
            file_put_contents("websocket.log",'stop pid'.$managerPid." : ".$masterPid.PHP_EOL,FILE_APPEND);
            \Swoole\Process::kill((int)$managerPid);
            \Swoole\Process::kill((int)$masterPid);
            cache('master_pid', NULL);
            cache('manager_pid', NULL);
        }
    }
    //启动服务
    public function startService(){
        $server = new \Swoole\WebSocket\Server("0.0.0.0", $this->port);
        $server->set([
            'daemonize' => false,
            'task_worker_num' => 3,
        ]);
        $server->on('start', function (\Swoole\WebSocket\Server $server) {
            $managerPid=$server ->master_pid ;
            $masterPid=$server->manager_pid ;
            cache('master_pid',$masterPid);
            cache('manager_pid',$managerPid);
            echo('start server:'.$managerPid." : ".$masterPid.PHP_EOL);
            file_put_contents("websocket.log",'start server:'.$managerPid." : ".$masterPid.PHP_EOL,FILE_APPEND);
        });
        $server->on('open', function (\Swoole\WebSocket\Server $server, $request) {

        });

        $server->on('message', function (\Swoole\WebSocket\Server $server, $frame) {
            echo "receive from {$frame->fd}:{$frame->data},opcode:{$frame->opcode},fin:{$frame->finish}\n";
            file_put_contents("websocket.log",date("Y-m-d H:i:s ")."receive from {$frame->fd}:{$frame->data},opcode:{$frame->opcode},fin:{$frame->finish}\n".PHP_EOL,FILE_APPEND);
            $server->push($frame->fd, "this is server");
            if($frame->data=='quit'){
                file_put_contents("websocket.log",date("Y-m-d H:i:s ").'客户端请求关闭'.PHP_EOL,FILE_APPEND);
                $server->push($frame->fd, "请求服务端关闭");
                $server->shutdown();
            }

        });

        $server->on('close', function ($server, $fd) {
            echo "client {$fd} closed\n";
        });

        $server->start();
        return $server;
    }
}
